public class J3 {
    //基本四则运算符：加减乘除模(+ - * / %)
    public static void main1(String[] args) {
        int a = 20;
        int b = 10;
        System.out.println(a + b); // 30
        System.out.println(a - b); // 10
        System.out.println(a * b); // 200
        System.out.println(a / b); // 2   *** b不能为0
        System.out.println(a % b); // 0 --->模运算相当于数学中除法的余数
        //都是⼆元运算符，使⽤时必须要有左右两个操作数
    }
    // 除法
    public static void main2(String[] args) {
        int a = 3;
        int b = 2;

        System.out.println(a / b);//1

        double d = a*1.0 / b;//1.5
        System.out.println(d);
    }
    //取余
    public static void main3(String[] args) {
        System.out.println(7%3);
        System.out.println(-7%3);
        System.out.println(7%-3);
        System.out.println(-7%-3);//1,-1,1,-1
        //% 不仅可以对整型取模，也可以对double类型取模，但是没有意义，⼀般都是对整型取模的
        System.out.println(11.5 % 2.0);// 运⾏结果1.5
    }

    //增量运算符+= -= *= %=
    public static void main4(String[] args) {
        int a = 1;
        a += 2; // 相当于 a = a + 2
        System.out.println(a); // 输出3
        a -= 1; // 相当于 a = a - 1
        System.out.println(a); // 输出2
        a *= 3; // 相当于 a = a * 3
        System.out.println(a); // 输出6
        a /= 3; // 相当于 a = a / 3
        System.out.println(a); // 输出2
        a %= 3; // 相当于 a = a % 2
        System.out.println(a); // 输出2


        double c= 10.4;
        int b = 10;
        b +=c; //不会报错   b=(int)(b+c)
        System.out.println(b);//20
       // b = b +c; //此时会编译报错，等号右边被提升为了double类型
    }

    //自增自减运算符
    public static void main5(String[] args) {
        int a = 1;
        a++; // 后置++ 表⽰给a的值加1，此时a的值为2
        System.out.println(a++); // 注意：后置++是先使⽤变量原来值，表⽰式结束时给变量+1，因此输出2
        System.out.println(a); // 输出3
        ++a; // 前置++ 表⽰给a的值加1
        System.out.println(++a); // 注意：前置++是先给变量+1，然后使⽤变量中的值，因此输出5
        System.out.println(a); // 输出5
        // --操作符给操作-1，与++含义类似
    }

    //关系运算符：< > <= >= == !=,其结果为true或false
    public static void main6(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println(a == b); // false
        System.out.println(a != b); // true
        System.out.println(a < b); // true
        System.out.println(a > b); // false
        System.out.println(a <= b); // true
        System.out.println(a >= b); // false
    }

    //逻辑运算符：&& || !,逻辑运算符的运算结果为true或false
    // && 逻辑与：当两个操作数都为true时，结果为true，否则为false
    public static void main7(String[] args) {
        int a = 1;
        int b = 2;
        System.out.println(a == 1 && b == 2); // 左为真 且 右为真 则结果为真
        System.out.println(a == 1 && b > 100); // 左为真 但 右为假 则结果为假
        System.out.println(a > 100 && b == 2); // 左为假 但 右为真 则结果为假
        System.out.println(a > 100 && b > 100); // 左为假 且 右为假 则结果为假
    }
    // || 逻辑或：当两个操作数有一个为true时，结果为true，否则为false
    public static void main8(String[] args) {
        int a = 1;
        int b = 2;
        System.out.println(a == 1 || b == 2); // 左为真 或 右为真 则结果为真
        System.out.println(a == 1 || b > 100); // 左为真 或 右为假 则结果为真
        System.out.println(a > 100 || b == 2); // 左为假 或 右为真 则结果为真
        System.out.println(a > 100 || b > 100);// 左为假 或 右为假 则结果为假
    }
    // ! 逻辑非：将操作数的结果取反，即true变为false，false变为true
    public static void main9(String[] args) {
        int a = 1;
        System.out.println(!(a == 1)); // 逻辑非，结果为false
        System.out.println(!(a > 1)); // 逻辑非，结果为true
    }
    //短路求值
    public static void main10(String[] args) {
        //&& 和 || 遵守短路求值的规则.
        System.out.println(10 > 20 && 10 / 0 == 0); // 打印 false
        System.out.println(10 < 20 || 10 / 0 == 0); // 打印 true
        //对于 && , 如果左侧表达式值为 false, 则表达式结果⼀定是 false, ⽆需计算右侧表达式.
        //对于 ||, 如果左侧表达式值为 true, 则表达式结果⼀定是 true, ⽆需计算右侧表达式.

        //& 和 | 如果表达式结果为 boolean 时, 也表⽰逻辑运算. 但与 && || 相⽐, 它们不⽀持短路求值.
       // System.out.println(10 > 20 & 10 / 0 == 0); // 程序抛出异常
        //System.out.println(10 < 20 | 10 / 0 == 0); // 程序抛出异常

        System.out.println(10 > 20 & 10 > 0);//false
        System.out.println(10 < 20 & 10 > 0);// true
        System.out.println(10 < 20 | 10 > 0);// true
        System.out.println(10 > 20 | 10 < 0);// false
    }
    //位运算符 & | ~ ^ ，除 ~ 是⼀元运算符外，其余都是⼆元运算符。
    public static void main11(String[] args) {
        //按位与 &: 如果两个⼆进制位都是 1, 则结果为 1, 否则结果为 0.
        int a = 10;
        int b = 20;
        System.out.println(a & b);
        //00001010&00010100=00000000

        //按位或 |: 如果两个⼆进制位都是 0, 则结果为 0, 否则结果为 1.
        System.out.println(a | b);
        //00001010|00010100=00011110
        //**当 & 和 | 的操作数为整数(int, short, long, byte) 的时候, 表⽰按位运算, 当操作数为 boolean 的时候, 表⽰逻辑运算.

        //按位取反 ~: 如果该位为 0 则转为 1, 如果该位为 1 则转为 0
        int c = 0xf;
        System.out.printf("%x\n", ~c);
        //f=1111  c=0000000f        结果：fffffff0

        //按位异或 ^: 如果两个数字的⼆进制位相同, 则结果为 0, 相异则结果为 1
        int d = 0x1;
        int e = 0x2;
        System.out.printf("%x\n", d ^ e);
        //00000001^00000010=00000011
    }

    //移位运算(了解)
    //移位运算符有三个: << >> >>> ，都是⼆元运算符，且都是按照⼆进制⽐特位来运算的。
    public static void main12(String[] args) {
        //左移 <<  最左侧位不要了, 最右侧补 0.
        int a = 0x10;
        System.out.printf("%x\n", a << 1);// 运⾏结果(注意, 是按⼗六进制打印的)20
        //注意：向左移位时，丢弃的是符号位，因此正数左移可能会变成负数。
        //0x00000010 00010000b  <<1  00100000b  (20)十六进制表示

         //右移 >> 最右侧位不要了, 最左侧补符号位(正数补0, 负数补1)
        int b = 0x10;
        System.out.printf("%x\n", b >> 1);// 运⾏结果(注意, 是按⼗六进制打印的)20
        //0x00000010 00010000b  >>1  00001000b   (8)十六进制表示
        int c = 0xffff0000;
        System.out.printf("%x\n", c >> 1);
        // 运⾏结果(注意, 是按⼗六进制打印的)
        //ffff0000   >>1 左边补1
        //ffff8000

        // ⽆符号右移 >>>最右侧位不要了, 最左侧补 0.
        int d = 0xffffffff;
        System.out.printf("%x\n", d >>> 1);
        // 运⾏结果(注意, 是按⼗六进制打印的)7fffffff
    }

    //条件运算符  表达式1 ? 表达式2 : 表达式3
    //当 表达式1 的值为 true 时, 整个表达式的值为 表达式2 的值;
    //当 表达式1 的值为 false 时, 整个表达式的值为 表达式3 的值.
    public static void main13(String[] args) {
        // 求两个整数的最⼤值
        int a = 10;
        int b = 20;
        int max = a > b ? a : b;
       //注意：

        //表达式2和表达式3的结果要是同类型的，除⾮能发⽣类型隐式类型转换
        // int c = a > b? 1 : 2.0;

        //表达式不能单独存在，其产⽣的结果必须要被使⽤。
        // a > b? a : b; // 报错：Error:(15, 14) java: 不是语句
    }

    //运算符的优先级
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int c = a + (b - a) >> 1;
        System.out.println(c);
        //00010100   >>1  00001010(10)
        int d = a + ((b - a) >> 1);
        System.out.println(d);
        //00001010+(00001010>>1)    00001010+00000101=00001111(15)
    }
}
